package com.course.config;

import com.common.handler.ExchangeServiceHandler;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.retry.MessageRecoverer;
import org.springframework.amqp.rabbit.retry.RepublishMessageRecoverer;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RabbitMqConfiguration {
    /**
     * 配置消息转换器
     *
     * @return
     */
    @Bean
    public MessageConverter messageConverter(ObjectMapper objectMapper) {
        return new Jackson2JsonMessageConverter(objectMapper);
    }

    /**
     * 消费者执行任务失败并且重试以后依然失败 ， 则需要使用`MessageRecoverer`接口来处理 , 内部包含三种不同的实现类
     * RejectAndDontRequeueRecoverer ： 重连次数耗尽，直接采用【reject】返回机制，拒绝该消息，并且删除 【默认实现】
     * ImmediateRequeueMessageRecoverer ： 重试耗尽后，返回【nack】。消息重新入队列 不断尝试重发
     * RepublishMessageRecovere ： 重连耗尽后，将失败消息投递到指定的交换机 ， 类似于当消息无法被当前消费者处理的时候 ，
     * 可以投入一个指定的交换机，该交换机只处理这种异常的消息，使用消费者监听这种异常交换机绑定的队列，每次监听到消息都可以告诫开发人员，达到一种人工处理的方案。
     */
    @Bean
    public MessageRecoverer RepublishMessageRecoverer(RabbitTemplate rabbitTemplate) {
        String exchangeName = ExchangeServiceHandler.ERROR_EXCHANGE; // 异常处理的交换机名称
        String RoutingKey = "course.error.message";    // 异常处理的交换机与队列绑定的RoutingKey
        return new RepublishMessageRecoverer(rabbitTemplate, exchangeName, RoutingKey);
    }


}
